home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / watcom / w_modey / yblitbuf.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-12  |  13.9 KB  |  640 lines

  1. #include <conio.h>
  2. #include <mem.h>
  3. #include <stdio.h>
  4.  
  5. #include "yprim.hpp"
  6. #include "ypal.hpp"
  7. #include "yblitbuf.hpp"
  8.  
  9.  
  10. void
  11. clear_blitbuf(blitbuf *buf)
  12. {
  13.     buf->xsize = 0;
  14.     buf->ysize = 0;
  15.  
  16.     delete buf->image;
  17. }
  18.  
  19.  
  20. void
  21. fill_blitbuf(BYTE color, blitbuf *buf)
  22. {
  23.     memset(buf->image, color, buf->xsize * buf->ysize);
  24. }
  25.  
  26.  
  27. void
  28. alloc_blitbuf(blitbuf *buf, DIST xsize, DIST ysize)
  29. {
  30.     buf->xsize = xsize;
  31.     buf->ysize = ysize;
  32.     buf->image = new BYTE[xsize * ysize];
  33. }
  34.  
  35.  
  36. void
  37. bitblit(COORD x, COORD y, blitbuf *buf)
  38. {
  39.     short int i, xsize;
  40.     BYTE *vga_ptr;
  41.     BYTE *buf_ptr;
  42.  
  43.     xsize   = buf->xsize;
  44.     buf_ptr = buf->image;
  45.     vga_ptr = RowsY[y] + x;
  46.  
  47.     i=buf->ysize;
  48.     while (i--) {
  49.         memcpy(vga_ptr, buf_ptr, xsize);
  50.         buf_ptr += xsize;
  51.         vga_ptr += 320;
  52.     }
  53. }
  54.  
  55.  
  56. void
  57. getblit(COORD x, COORD y, blitbuf *buf)
  58. {
  59.     short int i, xsize;
  60.     BYTE *vga_ptr;
  61.     BYTE *buf_ptr;
  62.  
  63.     xsize   = buf->xsize;
  64.     buf_ptr = buf->image;
  65.     vga_ptr = RowsY[y] + x;
  66.  
  67.     i=buf->ysize;
  68.     while (i--) {
  69.         memcpy(buf_ptr, vga_ptr, xsize);
  70.         buf_ptr += xsize;
  71.         vga_ptr += 320;
  72.     }
  73. }
  74.  
  75.  
  76. void
  77. transparent_bitblit(COORD x, COORD y, blitbuf *buf)
  78. {
  79.     short int i, j, xsize, skip;
  80.     BYTE *vga_ptr;
  81.     BYTE *buf_ptr;
  82.  
  83.     skip    = 320 - xsize;
  84.     xsize   = buf->xsize;
  85.     buf_ptr = buf->image;
  86.     vga_ptr = RowsY[y] + x;
  87.  
  88.     i=buf->ysize;
  89.     while (i--) {
  90.         j=xsize;
  91.         while (j--) {
  92.             if (*buf_ptr) {
  93.                 *vga_ptr = *buf_ptr;
  94.             }
  95.             vga_ptr++;
  96.             buf_ptr++;
  97.         }
  98.         vga_ptr += skip;
  99.     }
  100. }
  101.  
  102.  
  103. void
  104. save_blitbufPCX(char *fname, blitbuf *buf)
  105. {
  106.     FILE *fp;
  107.     unsigned int i, size, temp_int;
  108.     BYTE VGA_pal[768];
  109.     BYTE *buf_ptr;
  110.     BYTE temp_char, match, count;
  111.  
  112.     fp = fopen(fname, "wb");
  113.  
  114.     if (fp != NULL) {
  115.         // Write manufacturer's byte
  116.         temp_char = 10;
  117.         fwrite(&temp_char, 1, 1, fp);
  118.  
  119.         // Write version of PCX.  5 = 256 color (PCX Version 5.0)
  120.         temp_char = 5;
  121.         fwrite(&temp_char, 1, 1, fp);
  122.  
  123.         // Write encoding type, always 1 for RLE.
  124.         temp_char = 1;
  125.         fwrite(&temp_char, 1, 1, fp);
  126.  
  127.         // Write bits_per_pixel = 8.
  128.         temp_char = 8;
  129.         fwrite(&temp_char, 1, 1, fp);
  130.  
  131.         // Write starting X and Y coords
  132.         temp_int = 0;
  133.         fwrite(&temp_int, 2, 1, fp);
  134.         fwrite(&temp_int, 2, 1, fp);
  135.  
  136.         // Write X size
  137.         temp_int = (buf->xsize - 1);
  138.         fwrite(&temp_int, 2, 1, fp);
  139.  
  140.         // Write Y size
  141.         temp_int = (buf->ysize - 1);
  142.         fwrite(&temp_int, 2, 1, fp);
  143.  
  144.         // Do HRES and VRES **
  145.         temp_int = buf->xsize;
  146.         fwrite(&temp_int, 2, 1, fp);
  147.         temp_int = buf->ysize;
  148.         fwrite(&temp_int, 2, 1, fp);
  149.  
  150.         // Write 16 color palette, not used.
  151.         temp_int = 0;
  152.         i=24;
  153.         while (i--) {
  154.             fwrite(&temp_int, 2, 1, fp);
  155.         }
  156.  
  157.         // Write vmode byte.
  158.         temp_char = 0;
  159.         fwrite(&temp_char, 1, 1, fp);
  160.  
  161.         // Write bit_planes
  162.         temp_char = 1;
  163.         fwrite(&temp_char, 1, 1, fp);
  164.  
  165.         // Write bytes_per_line
  166.         temp_int = buf->xsize;
  167.         fwrite(&temp_int, 2, 1, fp);
  168.  
  169.         // Write palette type
  170.         temp_int = 1;
  171.         fwrite(&temp_int, 2, 1, fp);
  172.  
  173.         // Write junk filler
  174.         temp_int = 0;
  175.         i=29;
  176.         while (i--) {
  177.             fwrite(&temp_int, 2, 1, fp);
  178.         }
  179.  
  180.         // Write the actual image
  181.         buf_ptr = buf->image;
  182.         size = (buf->xsize * buf->ysize);
  183.  
  184.         count = 0;
  185.         match = *buf_ptr;
  186.  
  187.         i=size;
  188.         while (i--) {
  189.             temp_char = *buf_ptr++;
  190.  
  191.             if ((temp_char == match) && (count < 63)) {
  192.                count++;
  193.             } else {
  194.                 if ((count == 1) && (match < 192)) {
  195.                     // Write single byte
  196.                     fwrite(&match,1,1,fp);
  197.                 } else {
  198.                     // Write run of pixels
  199.                     count += 192;
  200.                     fwrite(&count, 1, 1, fp);
  201.                     fwrite(&match, 1, 1, fp);
  202.                 }
  203.                 count = 1;
  204.                 match = temp_char;
  205.             }
  206.         }
  207.  
  208.         if ((count == 1) && (match < 192)) {
  209.             // Write single byte
  210.             fwrite(&match,1,1,fp);
  211.         } else {
  212.             // Write run of pixels
  213.             count += 192;
  214.             fwrite(&count, 1, 1, fp);
  215.             fwrite(&match, 1, 1, fp);
  216.         }
  217.  
  218.         // Write palette verification byte
  219.         temp_char = 12;
  220.         fwrite(&temp_char, 1, 1, fp);
  221.  
  222.         get_palette(VGA_pal);
  223.  
  224.         // Write 256 color palette
  225.         fwrite(VGA_pal, 1, 768, fp);
  226.  
  227.         fclose(fp);
  228.     }
  229. }
  230.  
  231.  
  232. int
  233. load_blitbufPCX(char *fname, blitbuf *buf)
  234. {
  235.     FILE *fp;
  236.     int size;
  237.     BYTE VGA_pal[768];
  238.     BYTE PCX_byte, RLE_byte;
  239.     BYTE *buf_ptr;
  240.     BYTE *end_of_buf;
  241.  
  242.     fp = fopen(fname, "rb");
  243.  
  244.     if (fp == NULL) {
  245.         buf->xsize = 0;
  246.         buf->ysize = 0;
  247.         buf->image = NULL;
  248.         return 0;
  249.     } else {
  250.         fseek(fp, 8, SEEK_SET);
  251.         fread(&buf->xsize, 2, 1, fp);
  252.         fread(&buf->ysize, 2, 1, fp);
  253.  
  254.         buf->xsize++;
  255.         buf->ysize++;
  256.  
  257.         size = (buf->xsize * buf->ysize);
  258.  
  259.         buf->image = new BYTE[size];
  260.         buf_ptr = buf->image;
  261.         end_of_buf = buf_ptr + size;
  262.  
  263.         // Load 256 color PCX palette
  264.         fseek(fp, -768, SEEK_END);
  265.         fread(VGA_pal, 1, 768, fp);
  266.  
  267.         set_palette(VGA_pal);
  268.  
  269.         fseek(fp, 128, SEEK_SET);
  270.  
  271.         while (buf_ptr < end_of_buf) {
  272.             // Read next packet
  273.             fread(&PCX_byte, 1, 1, fp);
  274.  
  275.             if (PCX_byte < 192) {
  276.                 // Raw Pixel
  277.                 *buf_ptr++ = PCX_byte;
  278.             } else {
  279.                 // RLE Pixels
  280.                 PCX_byte = PCX_byte & 0x3F;
  281.                 fread(&RLE_byte, 1, 1, fp);
  282.                 memset(buf_ptr, RLE_byte, PCX_byte);
  283.                 buf_ptr += PCX_byte;
  284.             }
  285.         }
  286.  
  287.         fclose(fp);
  288.         return 1;
  289.     }
  290. }
  291.  
  292.  
  293. void
  294. scale_blitbuf(DIST dest_x, DIST dest_y, blitbuf *buf1, blitbuf *buf2)
  295. {
  296.     unsigned long ErrorAccX, ErrorAccY, ErrorAdjX, ErrorAdjY;
  297.     DIST oldx, oldy, newx, newy;
  298.     short int i, j, count;
  299.     BYTE *src_base;
  300.     BYTE *src_ptr;
  301.     BYTE *dest_ptr;
  302.     BYTE *newbuf;
  303.  
  304.     oldx = buf1->xsize;
  305.     oldy = buf1->ysize;
  306.     newx = dest_x;
  307.     newy = dest_y;
  308.  
  309.     newbuf = new BYTE[newx * newy];
  310.  
  311.     src_base = buf1->image;
  312.     dest_ptr = newbuf;
  313.  
  314.     // My bitmap scaling routine.  As you probably noticed, it's
  315.     // pretty Bresenhammy!
  316.  
  317.     ErrorAccY = 0x8000;
  318.  
  319.     if (newx > oldx) {
  320.         // Biggering
  321.         ErrorAdjX = ((((unsigned long)newx) << 16) /
  322.                      (((unsigned long)oldx)));
  323.  
  324.         ErrorAdjY = ((((unsigned long)newy) << 16) /
  325.                      (((unsigned long)oldy)));
  326.  
  327.         i=oldy;
  328.         while (i--) {
  329.             ErrorAccX = 0x8000;
  330.             src_ptr = src_base;
  331.  
  332.             j=oldx;
  333.             while (j--) {
  334.                 ErrorAccX += ErrorAdjX;
  335.                 if (count = (ErrorAccX >> 16)) {
  336.                     ErrorAccX &= 0xFFFFL;
  337.                     while (count--) {
  338.                         *dest_ptr++ = *src_ptr;
  339.                     }
  340.                 }
  341.                 src_ptr++;
  342.             }
  343.  
  344.             ErrorAccY += ErrorAdjY;
  345.             count = (ErrorAccY >> 16) - 1;
  346.             while (count--) {
  347.                 memcpy(dest_ptr, dest_ptr - newx, newx);
  348.                 dest_ptr += newx;
  349.             }
  350.             ErrorAccY &= 0xFFFFL;
  351.             src_base += oldx;
  352.         }
  353.     } else {
  354.         // Smallering
  355.         ErrorAdjX = ((((unsigned long)oldx) << 16) /
  356.                      (((unsigned long)newx)));
  357.  
  358.         ErrorAdjY = ((((unsigned long)oldy) << 16) /
  359.                      (((unsigned long)newy)));
  360.  
  361.         i=newy;
  362.         while (i--) {
  363.             ErrorAccX = 0x8000;
  364.             src_ptr = src_base;
  365.  
  366.             j=newx;
  367.             while (j--) {
  368.                 *dest_ptr++ = *src_ptr;
  369.                 ErrorAccX += ErrorAdjX;
  370.                 src_ptr += (ErrorAccX >> 16);
  371.                 ErrorAccX &= 0xFFFFL;
  372.             }
  373.  
  374.             ErrorAccY += ErrorAdjY;
  375.             src_base += (oldx * (ErrorAccY >> 16));
  376.             ErrorAccY &= 0xFFFFL;
  377.         }
  378.     }
  379.  
  380.     if (buf2 == NULL) {
  381.         delete buf1->image;
  382.         buf1->xsize = newx;
  383.         buf1->ysize = newy;
  384.         buf1->image = newbuf;
  385.     } else {
  386.         if (buf2->image != NULL) {
  387.             delete buf2->image;
  388.         }
  389.         buf2->xsize = newx;
  390.         buf2->ysize = newy;
  391.         buf2->image = newbuf;
  392.     }
  393. }
  394.  
  395.  
  396. void
  397. vertical_scale_blitbuf(DIST dest_y, blitbuf *buf1, blitbuf *buf2)
  398. {
  399.     unsigned long ErrorAccY, ErrorAdjY;
  400.     DIST xsize, oldy, newy;
  401.     short int i, count;
  402.     BYTE *src_ptr;
  403.     BYTE *dest_ptr;
  404.     BYTE *newbuf;
  405.  
  406.     xsize = buf1->xsize;
  407.     oldy = buf1->ysize;
  408.     newy = dest_y;
  409.  
  410.     newbuf = new BYTE[xsize * newy];
  411.  
  412.     src_ptr = buf1->image;
  413.     dest_ptr = newbuf;
  414.  
  415.     // My bitmap scaling routine.  As you probably noticed, it's
  416.     // pretty Bresenhammy!
  417.  
  418.     ErrorAccY = 0x8000;
  419.     ErrorAdjY = ((((unsigned long)newy) << 16) /
  420.                  (((unsigned long)oldy)));
  421.  
  422.     if (newy >= oldy) {
  423.         // Biggering
  424.         i=oldy;
  425.         while (i--) {
  426.             ErrorAccY += ErrorAdjY;
  427.             if (count = (ErrorAccY >> 16)) {
  428.                 ErrorAccY &= 0xFFFFL;
  429.  
  430.                 while (count--) {
  431.                     memcpy(dest_ptr, src_ptr, xsize);
  432.                     dest_ptr += xsize;
  433.                 }
  434.             }
  435.  
  436.             src_ptr += xsize;
  437.         }
  438.     } else {
  439.         // Smallering
  440.         i=oldy;
  441.         while (i--) {
  442.             ErrorAccY += ErrorAdjY;
  443.             if (ErrorAccY & ~0xFFFFL) {
  444.                 ErrorAccY &= 0xFFFFL;
  445.                 memcpy(dest_ptr, src_ptr, xsize);
  446.                 dest_ptr += xsize;
  447.             }
  448.  
  449.             src_ptr += xsize;
  450.         }
  451.     }
  452.  
  453.     if (buf2 == NULL) {
  454.         delete buf1->image;
  455.         buf1->ysize = newy;
  456.         buf1->image = newbuf;
  457.     } else {
  458.         if (buf2->image != NULL) {
  459.             delete buf2->image;
  460.         }
  461.         buf2->xsize = xsize;
  462.         buf2->ysize = newy;
  463.         buf2->image = newbuf;
  464.     }
  465. }
  466.  
  467.  
  468. void
  469. greyscale_blitbuf(blitbuf *buf)
  470. {
  471.     BYTE temp_pal[768];
  472.     BYTE *buf_ptr;
  473.     BYTE *temp;
  474.     BYTE r, g;
  475.     unsigned int i;
  476.  
  477.     buf_ptr = buf->image;
  478.  
  479.     get_palette(temp_pal, 0);
  480.  
  481.     for (i = (buf->xsize * buf->ysize); i; i--) {
  482.         temp = temp_pal + ((*buf_ptr) * 3);
  483.         r = *temp++;
  484.         g = *temp++;
  485.  
  486.         *buf_ptr++ = ((r * 19) + (g * 37) + (*temp << 3)) >> 6;
  487.     }
  488. }
  489.  
  490.  
  491. void
  492. RGB_blitbuf(blitbuf *buf)
  493. {
  494.     BYTE temp_pal[768];
  495.     BYTE *buf_ptr;
  496.     BYTE *temp;
  497.     BYTE r, g, b;
  498.     unsigned int i;
  499.  
  500.     buf_ptr = buf->image;
  501.  
  502.     get_palette(temp_pal, 0);
  503.  
  504.     for (i = (buf->xsize * buf->ysize); i; i--) {
  505.         temp = temp_pal + ((*buf_ptr) * 3);
  506.         r = (*temp) + 4;
  507.         temp++;
  508.         g = (*temp) + 4;
  509.         temp++;
  510.         b = (*temp) + 8;
  511.  
  512.         *buf_ptr++ = ((r >> 3) << 5) + ((g >> 3) << 2) + (b >> 4);
  513.     }
  514. }
  515.  
  516.  
  517. void
  518. flip_vertical_blitbuf(blitbuf *buf)
  519. {
  520.     BYTE *top;
  521.     BYTE *bottom;
  522.     BYTE *temp;
  523.     DIST i, x, y;;
  524.  
  525.     x = buf->xsize;
  526.     y = buf->ysize;
  527.  
  528.     temp = new BYTE[x];
  529.  
  530.     top = buf->image;
  531.     bottom = buf->image + (x * (y-1));
  532.  
  533.     i = (y >> 1);
  534.     while (i--) {
  535.         memcpy(temp, top, x);
  536.         memcpy(top, bottom, x);
  537.         memcpy(bottom, temp, x);
  538.         top += x;
  539.         bottom -= x;
  540.     }
  541.  
  542.     delete temp;
  543. }
  544.  
  545.  
  546. void
  547. flip_horizontal_blitbuf(blitbuf *buf)
  548. {
  549.     BYTE *buf_ptr;
  550.     BYTE *temp_ptr;
  551.     BYTE *temp;
  552.     DIST i, j, x;
  553.  
  554.     x = buf->xsize;
  555.  
  556.     temp = new BYTE[x];
  557.  
  558.     buf_ptr = buf->image;
  559.  
  560.     i = buf->ysize;
  561.     while (i--) {
  562.         memcpy(temp, buf_ptr, x);
  563.         temp_ptr = temp + (x - 1);
  564.         j=x;
  565.         while (j--) {
  566.             *buf_ptr++ = *temp_ptr--;
  567.         }
  568.     }
  569.  
  570.     delete temp;
  571. }
  572.  
  573.  
  574. void
  575. scale_scanline(BYTE *source, BYTE *dest, DIST smap_size, DIST dmap_size,
  576.     DIST dline_size)
  577. {
  578.     unsigned long ErrorAcc, ErrorAdj;
  579.     short int i, temp, invert;
  580.  
  581.     ErrorAcc = 0x8000;
  582.  
  583.     // Prepare for backwards scanlines
  584.     if (dline_size >= 0) {
  585.         invert = 0;
  586.     } else {
  587.         invert = 1;
  588.         dline_size = -dline_size;
  589.     }
  590.  
  591.     if (dline_size > smap_size) {
  592.         // Biggering
  593.         if (smap_size == 0) {
  594.             return;
  595.         }
  596.         ErrorAdj = ((((unsigned long)dline_size) << 16) /
  597.                     (((unsigned long)smap_size)));
  598.  
  599.         i=smap_size;
  600.         while (i--) {
  601.             ErrorAcc += ErrorAdj;
  602.             temp = (ErrorAcc >> 16);
  603.             ErrorAcc &= 0xFFFFL;
  604.             while (temp--) {
  605.                 *dest++ = *source;
  606.             }
  607.             source++;
  608.         }
  609.     } else {
  610.         // Smallering
  611.         if (dline_size == 0) {
  612.             memset(dest, 0, dmap_size);
  613.         } else {
  614.             temp = dmap_size - dline_size;
  615.             i = temp >> 1;
  616.             temp -= i;
  617.             while (i--) {
  618.                 *dest++ = 0;
  619.             }
  620.  
  621.             ErrorAdj = ((((unsigned long)smap_size) << 16) /
  622.                         (((unsigned long)dline_size)));
  623.  
  624.             i=dline_size;
  625.  
  626.             while (i--) {
  627.                 *dest++ = *source;
  628.                 ErrorAcc += ErrorAdj;
  629.                 source += (ErrorAcc >> 16);
  630.                 ErrorAcc &= 0xFFFFL;
  631.             }
  632.  
  633.             while (temp--) {
  634.                 *dest++ = 0;
  635.             }
  636.         }
  637.     }
  638. }
  639.  
  640.